package good.idea.data.excel.read.template.impl;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import good.idea.data.excel.context.ExcelTemplateContext;
import good.idea.data.excel.entity.CellEntity;
import good.idea.data.excel.entity.RowEntity;
import good.idea.data.excel.read.template.ExcelTemplateService;
import good.idea.data.excel.read.template.TemplateHelper;
import good.idea.data.utils.FileUtils;
import good.idea.data.utils.LangUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author chm
 */
public class ExcelTemplateServiceImpl implements ExcelTemplateService {

    private ExcelTemplateContext context = new ExcelTemplateContext();

    @Override
    public ExcelTemplateContext readTemplate(InputStream templateInputStream) throws Exception {
        XSSFWorkbook workbook = new XSSFWorkbook(new BufferedInputStream(templateInputStream));
        context.setWorkbook(workbook);
        int sheetCount = workbook.getNumberOfSheets();
        boolean hasFlag = context.hasTemplateFile();
        if (hasFlag) {
            sheetCount = sheetCount / 2;
        }

        List<XSSFSheet> tempSheets = new ArrayList<>();
        for (int i = 0; i < sheetCount; i++) {
            XSSFSheet sheet = workbook.getSheetAt(i);
            context.setActivitySheetIndex(i);
            XSSFSheet tempSheet = null;
            if (hasFlag) {
                tempSheet = workbook.getSheetAt(i * 2 + 1);
            } else {
                tempSheet = workbook.cloneSheet(i);
                TemplateHelper.copyPrintSetup(sheet, tempSheet);
            }
            context.setActivitySheet(tempSheet);
            tempSheets.add(tempSheet);

            int rowNum = sheet.getLastRowNum();
            for (int r = 0; r <= rowNum; r++) {
                XSSFRow row = sheet.getRow(r);
                if (row != null) {
                    RowEntity rowEntity = new RowEntity();
                    rowEntity.setThisRow(row);
                    TemplateHelper.parserTemplateTag(context, rowEntity, r);
                    List<CellEntity> cells = rowEntity.getCellEntities();
                    context.getActiveCellEntities().addAll(cells);
                    context.getActiveRowEntities().add(rowEntity);
                }
            }
            if (!hasFlag) {
                TemplateHelper.clearSheetContent(context);
            }
        }
        context.setTempSheets(tempSheets);
        this.setTemplateRecord();
        return context;
    }

    @Override
    public ExcelTemplateContext readTemplate(File file) throws Exception {
        String name = file.getName();
        FileInputStream fileInputStream = new FileInputStream(file);
        return this.readTemplate(fileInputStream);
    }

    @Override
    public ExcelTemplateContext readTemplate(String template) throws Exception {
        context.setTemplateName(template);
        ClassLoader load = ExcelTemplateServiceImpl.class.getClassLoader();
        InputStream inputStream = load.getResource(template).openStream();
        return this.readTemplate(inputStream);
    }

    public void setTemplateRecord() {
        String template = context.getTemplateName();
        Map<String, String> tempFileNameMap = TemplateHelper.TEMP_FILE_NAME_MAP;
        String name = tempFileNameMap.get(template);
        if (LangUtils.isEmpty(name)) {
            String uuid = UUID.randomUUID().toString();
            name = this.createTemplateFile(uuid);
            tempFileNameMap.put(template, name);
        }
    }

    public String createTemplateFile(String uuid) {
        OutputStream outputStream = null;
        try {
            String systemTempPath = System.getProperty("java.io.tmpdir");
            String name = systemTempPath + "/idea-excel-template/" + uuid + "/0.xlsx";
            File file = new File(name);
            FileUtils.mkdirs(file.getParent());
            file.createNewFile();
            context.getTemplateFiles().add(file);
            XSSFWorkbook workbook = context.getWorkbook();
            outputStream = new FileOutputStream(file);
            workbook.write(outputStream);
            return name;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                }
            }
        }
        return null;
    }


}
